#include "StdAfx.h"
#include "LModel.h"
#include "SearchManager.h"
#include "QueryManager.h"
#include "QueryTerm.h"
#include <algorithm>

const static double mu = 1500.0;


LModel::LModel(SearchManager * pSM, QueryManager * pQM, std::string outFile):RankingModel(pSM, pQM, outFile)
{
	m_ofs.open(outFile);
}


LModel::~LModel(void)
{
	if(m_ofs.is_open() == true)
		m_ofs.close();
}

void LModel::RankingQuery(unsigned int queryIndex, unsigned int printCount )
{
	QueryTerm *pQueryTerm = m_pQueryManager->GetQueryTerm(queryIndex);
		
	if( pQueryTerm == 0 )
		return ;

	DocumentManager *pDocumentManager = m_pSearchManager->GetDocumentManager();

	// Get Query Term & Term Weight
	QueryTermMap queryTermMap = pQueryTerm->GetTermFrequency();

	ScoreMap scoreMap;
	scoreMap.clear();

	docRanking.clear();

	for( QueryTermMap::iterator it = queryTermMap.begin(); it != queryTermMap.end(); ++it )
	{
		TermData termData;
		IndexData* pData = m_pSearchManager->FindIndexData(it->first, termData);
		
		// Get df, cf
		unsigned int DF = termData.df;
		unsigned int CF = termData.cf;
		
		// Get Collection Length
		unsigned int CL = pDocumentManager->GetCollectionLength();

		while( pData != 0 )
		{
			unsigned int docIndex = pData->documentIndex;

			// Get DL
			unsigned int DL = pDocumentManager->GetDocumentLength(docIndex);

			double score = log((static_cast<float>(pData->tf) + (mu * static_cast<float>(CF) / static_cast<float>(CL)))/(static_cast<float>(DL) + mu));

			if( scoreMap.find(docIndex) == scoreMap.end() )
				scoreMap.insert(ScoreMap::value_type(docIndex, score) );
			else
				scoreMap[docIndex] += score;

			pData = m_pSearchManager->NextIndexData();
		}
	}

	for ( ScoreMap::iterator iter = scoreMap.begin(); iter != scoreMap.end(); ++iter )
		docRanking.push_back( std::make_pair( iter->first, iter->second) );
		
	sort( docRanking.begin(), docRanking.end(), ascending);
	
	this->DisplayResult(queryIndex, printCount);
}